package com.example;

// 测试目的：
// 确定因调用shareObject.wait()而进入waiting状态的线程被interrupt后是否立即抛出 InterruptException
// 还是要等当前线程重新获得锁之后才会抛出 InterruptException
// 结论：waiting的线程被中断后并不会立即抛出InterruptException，而是要等它重新获取到shareObject的监视器锁之后才会抛出InterruptException
//
public class ThreadWaitingTest2 {

    public static class TestThread extends Thread{

        private final Object shareObject;

        public TestThread(Object shareObject){
            super("test");
            this.shareObject = shareObject;
        }

        @Override
        public void run() {

            synchronized (shareObject){
                try {
                    System.out.println("test线程即将进入waiting状态...");
                    shareObject.wait();
                }catch (InterruptedException e){
                    e.printStackTrace();
                    // 可以发现，当shareObject.wait()方法抛出InterruptedException的时候会清除当前线程的中断状态
                    System.out.println("测试线程isInterrupted?: " + this.isInterrupted());
                }
            }

        }
    }

    public static void main(String[] args) throws InterruptedException {

        Object shareObject = new Object();
        TestThread testThread = new TestThread(shareObject);
        testThread.start();

        Thread.sleep(1000*2);
        synchronized (shareObject){
            System.out.println("主线程抢到了shareObject的监视器锁");
            System.out.println("开始中断test线程");
            testThread.interrupt();
            System.out.println("已经调用test线程的interrupt()方法，现在test线程的状态为：" + testThread.getState());
            System.out.println("test线程-isInterrupted：" + testThread.isInterrupted());
            System.out.println("主线程sleep 20秒，从而确保在此期间shareObject的监视器锁依旧被主线程持有");
            Thread.sleep(1000*20);
            System.out.println("主线程即将释放shareObject的监视器锁");
        }
    }
}
